#include "adc_hw.h"
#include "globalDef.h"







#if 1		//不适用DMA，如果不使用的IO可以不用初始化，主要为了省电

/*
输入参数4~7对应adc4~7
*/
void adc_config(uint8_t ch)
{
	
	/* reset ADC */
  adc_deinit(ADC0);
	
	/* enable GPIOA clock */
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	
	/* enable ADC0 clock */
	rcu_periph_clock_enable(RCU_ADC0);
	
	
	/* config ADC clock */
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
		
	
	switch(ch)
	{
		case 0x00:
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0);
			break;
		case 0x01:
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_1);
			break;		
		case 0x04:
			
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_4);
			break;
		
		case 0x05:
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_5);
			break;
		
		case 0x06:
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_6);
			break;
		case 0x07:
			gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_7);
			break;		
		case 0x09:
			gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_1);
			break;
		default:
			return;
	}
		
	
	
	/* ADC continuous function disable */
	adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);	//ENABLE
	adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);
	/* ADC trigger config */
	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE); 
	/* ADC data alignment config */
	adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
	/* ADC mode config */
	adc_mode_config(ADC_MODE_FREE); 
	/* ADC channel length config */
	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);

	/* ADC DMA function enable */
	//adc_dma_mode_enable(ADC0);


	/* ADC regular channel config ???可以都写成0*/
	switch(ch)
	{
		case 0x00:
			//2M 470k
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x01:
			//2M 470k
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x04:
			//2M 470k
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x05:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
			break;
			//2M 470k
		case 0x06:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x07:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x09:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
			break;
		default:
			break;
	}
	

	/* ADC trigger config */
  adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
  adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

	/* ADC discontinuous mode */
	adc_discontinuous_mode_config(ADC0, ADC_REGULAR_CHANNEL, 1);

//	/* enable ADC interface */
//	adc_enable(ADC0);
//	
//	/* ADC calibration and reset calibration */
//	adc_calibration_enable(ADC0);
//	
//	/* ADC software trigger enable */
//	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
}



/*
获取5个通道的adc值
0: PA0
1: 去掉了
2：PA2
3：PA3
4：PA4
*/
uint16_t getAdcValue(uint8_t ch)
{
	uint16_t result=0;

	uint32_t timeout = 0xFFFF;

	
	rcu_periph_clock_enable(RCU_ADC0);
	adc_enable(ADC0);
	/* ADC calibration and reset calibration */
	adc_calibration_enable(ADC0);
	
	adc_flag_clear(ADC0,ADC_FLAG_EOC);

	
	/* ADC regular channel config ???可以都写成0*/
	switch(ch)
	{
		case 0x00:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x01:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
			break;
		case 0x04:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x05:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x06:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x07:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
			break;
		case 0x09:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
			break;
		default:
			return 0;
	}
	
	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
	while ((!(adc_flag_get(ADC0,ADC_FLAG_EOC))) && (0 != timeout))
	{
		timeout--;
	}

	result = adc_regular_data_read(ADC0);

	//关闭ADC
	/* enable ADC interface */
	adc_disable(ADC0);
	rcu_periph_clock_disable(RCU_ADC0);
	

	
	return result;
}


/*
获取4个通道的adc值,换算的电压值
0: PA0
1: 去掉了
2：PA2
3：PA3
4：PA4
*/
uint16_t getAdcVolt(uint8_t ch)
{
	uint32_t result=0;
	
	uint32_t timeout = 0xFFFF;
	
	rcu_periph_clock_enable(RCU_ADC0);
	adc_enable(ADC0);
	adc_flag_clear(ADC0,ADC_FLAG_EOC);
	
	/* ADC regular channel config ???可以都写成0*/
	switch(ch)
	{
		case 0x00:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x01:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
			break;
		case 0x04:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x05:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
			break;

		
		case 0x06:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x07:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
			break;
		
		case 0x09:
			adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
			break;
		default:
			break;
	}
	
	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
	while ((!(adc_flag_get(ADC0,ADC_FLAG_EOC))) && (0 != timeout))
	{
		timeout--;
	}

	result = adc_regular_data_read(ADC0);
	
	switch(ch)
	{
		case 0x00:
			result = result * 3310 * 11 / 4096;
			break;
		case 0x01:
			//200k 47k分压
			result = result * 3310 * 247 / 4096 / 47;
			break;
		
		case 0x04:

			result = result * 3310 * 247 / 4096 / 47;
			break;
		case 0x05:
			//200k 47k分压
			result = result * 3310 * 247 / 4096 / 47;
			break;
		
		case 0x06:
			//200k 47k分压
			result = result * 3310 * 247 / 4096 / 47;
			break;
		
		case 0x07:
			//200k 47k分压
			result = result * 3310 * 247 / 4096 / 47;
			break;
		
		case 0x09:
			//200k 47k·??1
			result = result * 3310 * 247 / 4096 / 47;
			break;
		default:
			result = 0;
			break;
	}
	
	

	
	return (uint16_t)result;
}


#endif


#if def_use_dma_adc
uint16_t adc_value[5];

/*
初始化参数，如果是使用DMA，一次初始化所有5路输入
ch写任意值。
增加输入参数是为了兼容非DMA常规模式
*/
void adc_config(uint8_t ch)
{
	/* ADC_DMA_channel configuration */
  dma_parameter_struct dma_data_parameter;
	
	/* reset ADC */
  adc_deinit(ADC0);

	/* ADC DMA_channel configuration */
	dma_deinit(DMA0, DMA_CH0);

	/* enable GPIOA clock */
	rcu_periph_clock_enable(RCU_GPIOA);
	
	/* enable ADC0 clock */
	rcu_periph_clock_enable(RCU_ADC0);
	
	/* enable DMA0 clock */
	rcu_periph_clock_enable(RCU_DMA0);  
	
	/* config ADC clock */
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
	
	
	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0|
						GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
						
	
	/* initialize DMA single data mode */
	dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
	dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_data_parameter.memory_addr = (uint32_t)(&adc_value);
	dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
	dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;  
	dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
	dma_data_parameter.number = 5;
	dma_data_parameter.priority = DMA_PRIORITY_HIGH;
	dma_init(DMA0, DMA_CH0, &dma_data_parameter);
	
	
	dma_circulation_enable(DMA0, DMA_CH0);
	
	/* ADC mode config */
	adc_mode_config(ADC_MODE_FREE); 
	
	/* ADC continuous function disable */
	adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
	adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
	
	
	/* ADC data alignment config */
	adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
	
	/* ADC channel length config */
	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 4);


	/* ADC regular channel config */
	adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
	//adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
	adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
	adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
	adc_regular_channel_config(ADC0, 3, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);

	/* ADC trigger config */
	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

	/* ADC discontinuous mode */
	//增加下面这句后，每次转换前必须使用 adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	//adc_discontinuous_mode_config(ADC0, ADC_REGULAR_CHANNEL, 4);
	
	
	/* ADC DMA function enable */
  adc_dma_mode_enable(ADC0);

	/* enable ADC interface */
	adc_enable(ADC0);
	/* ADC calibration and reset calibration */
	adc_calibration_enable(ADC0);
	

	/* enable DMA channel */
	dma_channel_enable(DMA0, DMA_CH0);

	/* ADC software trigger enable */
	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
}


/*
获取5个通道的adc值
*/
uint16_t getAdcValue(uint8_t ch)
{
	if (ch >= 4)
	{
		ch = 4;
	}
	
	return adc_value[ch];
}

#endif

